package message

import (
	"time"
)

// Service 消息服务接口
type Service interface {
	// 消息管理
	GetMessage(id uint) (*MessageDTO, error)
	CreateMessage(req *CreateMessageRequest) (*MessageDTO, error)
	UpdateMessage(id uint, req *UpdateMessageRequest) (*MessageDTO, error)
	DeleteMessage(id uint, operatorID uint) error
	ListMessages(query *MessageQuery) ([]*MessageDTO, int64, error)

	// 用户消息
	GetUserMessages(userID uint, query *UserMessageQuery) ([]*UserMessageDTO, int64, error)
	ReadMessage(userID uint, messageID uint) error
	BatchReadMessages(userID uint, messageIDs []uint) error
	DeleteUserMessage(userID uint, messageID uint) error
	BatchDeleteUserMessages(userID uint, messageIDs []uint) error
	CountUnreadMessages(userID uint) (int64, error)

	// 系统通知
	SendSystemNotification(req *SystemNotificationRequest) error
	SendAnnouncement(req *AnnouncementRequest) error
}

// MessageDTO 消息数据传输对象
type MessageDTO struct {
	ID        uint      `json:"id"`
	TenantID  uint      `json:"tenant_id"`
	SenderID  uint      `json:"sender_id"`
	Title     string    `json:"title"`
	Content   string    `json:"content"`
	Type      int       `json:"type"`
	TypeText  string    `json:"type_text"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`

	// 扩展字段
	ReceiverCount int `json:"receiver_count,omitempty"`
}

// UserMessageDTO 用户消息数据传输对象
type UserMessageDTO struct {
	ID         uint       `json:"id"`
	TenantID   uint       `json:"tenant_id"`
	SenderID   uint       `json:"sender_id"`
	Title      string     `json:"title"`
	Content    string     `json:"content"`
	Type       int        `json:"type"`
	TypeText   string     `json:"type_text"`
	Status     int        `json:"status"`
	StatusText string     `json:"status_text"`
	ReadTime   *time.Time `json:"read_time"`
	CreatedAt  time.Time  `json:"created_at"`
}

// CreateMessageRequest 创建消息请求
type CreateMessageRequest struct {
	TenantID    uint   `json:"tenant_id" binding:"required"`
	SenderID    uint   `json:"sender_id" binding:"required"`
	Title       string `json:"title" binding:"required,max=100"`
	Content     string `json:"content" binding:"required"`
	Type        int    `json:"type" binding:"required,min=1,max=3"`
	ReceiverIDs []uint `json:"receiver_ids" binding:"required,min=1"`
}

// UpdateMessageRequest 更新消息请求
type UpdateMessageRequest struct {
	Title   *string `json:"title" binding:"omitempty,max=100"`
	Content *string `json:"content"`
}

// SystemNotificationRequest 系统通知请求
type SystemNotificationRequest struct {
	TenantID    uint   `json:"tenant_id" binding:"required"`
	SenderID    uint   `json:"sender_id" binding:"required"`
	Title       string `json:"title" binding:"required,max=100"`
	Content     string `json:"content" binding:"required"`
	ReceiverIDs []uint `json:"receiver_ids" binding:"required,min=1"`
}

// AnnouncementRequest 公告请求
type AnnouncementRequest struct {
	TenantID    uint   `json:"tenant_id" binding:"required"`
	SenderID    uint   `json:"sender_id" binding:"required"`
	Title       string `json:"title" binding:"required,max=100"`
	Content     string `json:"content" binding:"required"`
	ReceiverIDs []uint `json:"receiver_ids" binding:"required,min=1"`
}

// DefaultService 默认服务实现
type DefaultService struct {
	repo Repository
}

// NewService 创建消息服务
func NewService(repo Repository) Service {
	return &DefaultService{repo: repo}
}

// GetMessage 获取消息信息
func (s *DefaultService) GetMessage(id uint) (*MessageDTO, error) {
	message, err := s.repo.GetMessageByID(id)
	if err != nil {
		return nil, err
	}

	// 获取接收者数量
	receivers, err := s.repo.GetMessageReceivers(id)
	if err != nil {
		return nil, err
	}

	dto := convertMessageToDTO(message)
	dto.ReceiverCount = len(receivers)

	return dto, nil
}

// CreateMessage 创建消息
func (s *DefaultService) CreateMessage(req *CreateMessageRequest) (*MessageDTO, error) {
	// 验证消息类型
	if req.Type < MessageTypeSystem || req.Type > MessageTypeAnnouncement {
		return nil, ErrInvalidMessageType
	}

	message := &Message{
		TenantID: req.TenantID,
		SenderID: req.SenderID,
		Title:    req.Title,
		Content:  req.Content,
		Type:     req.Type,
	}

	if err := s.repo.CreateMessage(message, req.ReceiverIDs); err != nil {
		return nil, err
	}

	return convertMessageToDTO(message), nil
}

// UpdateMessage 更新消息
func (s *DefaultService) UpdateMessage(id uint, req *UpdateMessageRequest) (*MessageDTO, error) {
	message, err := s.repo.GetMessageByID(id)
	if err != nil {
		return nil, err
	}

	if req.Title != nil {
		message.Title = *req.Title
	}

	if req.Content != nil {
		message.Content = *req.Content
	}

	if err := s.repo.UpdateMessage(message); err != nil {
		return nil, err
	}

	return convertMessageToDTO(message), nil
}

// DeleteMessage 删除消息
func (s *DefaultService) DeleteMessage(id uint, operatorID uint) error {
	message, err := s.repo.GetMessageByID(id)
	if err != nil {
		return err
	}

	// 检查权限：只有发送者可以删除消息
	if message.SenderID != operatorID {
		return ErrNoPermission
	}

	return s.repo.DeleteMessage(id)
}

// ListMessages 查询消息列表
func (s *DefaultService) ListMessages(query *MessageQuery) ([]*MessageDTO, int64, error) {
	messages, total, err := s.repo.ListMessages(query)
	if err != nil {
		return nil, 0, err
	}

	dtos := make([]*MessageDTO, len(messages))
	for i, message := range messages {
		dtos[i] = convertMessageToDTO(message)
	}

	return dtos, total, nil
}

// GetUserMessages 获取用户消息列表
func (s *DefaultService) GetUserMessages(userID uint, query *UserMessageQuery) ([]*UserMessageDTO, int64, error) {
	messages, total, err := s.repo.GetUserMessages(userID, query)
	if err != nil {
		return nil, 0, err
	}

	dtos := make([]*UserMessageDTO, len(messages))
	for i, message := range messages {
		dtos[i] = convertToUserMessageDTO(message)
	}

	return dtos, total, nil
}

// ReadMessage 标记消息为已读
func (s *DefaultService) ReadMessage(userID uint, messageID uint) error {
	return s.repo.UpdateMessageStatus(userID, messageID, MessageStatusRead)
}

// BatchReadMessages 批量标记消息为已读
func (s *DefaultService) BatchReadMessages(userID uint, messageIDs []uint) error {
	return s.repo.BatchUpdateMessageStatus(userID, messageIDs, MessageStatusRead)
}

// DeleteUserMessage 删除用户消息（标记为删除状态）
func (s *DefaultService) DeleteUserMessage(userID uint, messageID uint) error {
	return s.repo.UpdateMessageStatus(userID, messageID, MessageStatusDeleted)
}

// BatchDeleteUserMessages 批量删除用户消息
func (s *DefaultService) BatchDeleteUserMessages(userID uint, messageIDs []uint) error {
	return s.repo.BatchUpdateMessageStatus(userID, messageIDs, MessageStatusDeleted)
}

// CountUnreadMessages 统计未读消息数量
func (s *DefaultService) CountUnreadMessages(userID uint) (int64, error) {
	return s.repo.CountUnreadMessages(userID)
}

// SendSystemNotification 发送系统通知
func (s *DefaultService) SendSystemNotification(req *SystemNotificationRequest) error {
	message := &Message{
		TenantID: req.TenantID,
		SenderID: req.SenderID,
		Title:    req.Title,
		Content:  req.Content,
		Type:     MessageTypeSystem,
	}

	return s.repo.CreateMessage(message, req.ReceiverIDs)
}

// SendAnnouncement 发送公告
func (s *DefaultService) SendAnnouncement(req *AnnouncementRequest) error {
	message := &Message{
		TenantID: req.TenantID,
		SenderID: req.SenderID,
		Title:    req.Title,
		Content:  req.Content,
		Type:     MessageTypeAnnouncement,
	}

	return s.repo.CreateMessage(message, req.ReceiverIDs)
}

// 辅助函数：转换消息实体到DTO
func convertMessageToDTO(message *Message) *MessageDTO {
	dto := &MessageDTO{
		ID:        message.ID,
		TenantID:  message.TenantID,
		SenderID:  message.SenderID,
		Title:     message.Title,
		Content:   message.Content,
		Type:      message.Type,
		CreatedAt: message.CreatedAt,
		UpdatedAt: message.UpdatedAt,
	}

	// 设置类型文本
	switch message.Type {
	case MessageTypeSystem:
		dto.TypeText = "系统消息"
	case MessageTypePrivate:
		dto.TypeText = "私信"
	case MessageTypeAnnouncement:
		dto.TypeText = "公告"
	default:
		dto.TypeText = "未知类型"
	}

	return dto
}

// 辅助函数：转换用户消息到DTO
func convertToUserMessageDTO(message *MessageWithReceiver) *UserMessageDTO {
	dto := &UserMessageDTO{
		ID:        message.ID,
		TenantID:  message.TenantID,
		SenderID:  message.SenderID,
		Title:     message.Title,
		Content:   message.Content,
		Type:      message.Type,
		Status:    message.Status,
		ReadTime:  message.ReadTime,
		CreatedAt: message.CreatedAt,
	}

	// 设置类型文本
	switch message.Type {
	case MessageTypeSystem:
		dto.TypeText = "系统消息"
	case MessageTypePrivate:
		dto.TypeText = "私信"
	case MessageTypeAnnouncement:
		dto.TypeText = "公告"
	default:
		dto.TypeText = "未知类型"
	}

	// 设置状态文本
	switch message.Status {
	case MessageStatusUnread:
		dto.StatusText = "未读"
	case MessageStatusRead:
		dto.StatusText = "已读"
	case MessageStatusDeleted:
		dto.StatusText = "已删除"
	default:
		dto.StatusText = "未知状态"
	}

	return dto
}
